package com.videoanalysis.recognizer;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.tiia.v20190529.TiiaClient;
import com.tencentcloudapi.tiia.v20190529.models.DetectLabelItem;
import com.tencentcloudapi.tiia.v20190529.models.DetectLabelRequest;
import com.tencentcloudapi.tiia.v20190529.models.DetectLabelResponse;
import com.videoanalysis.RecognitionResult;
import com.videoanalysis.config.AppConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;

/**
 * 使用腾讯云图像识别服务的图像识别实现
 */
@Slf4j
public class TencentCloudImageRecognizer implements ImageRecognizer {
    private final TiiaClient client;
    private final AppConfig.TencentCloudConfig config;

    /**
     * 构造函数，初始化腾讯云图像识别客户端
     */
    public TencentCloudImageRecognizer() {
        this.config = AppConfig.getInstance().getTencentCloud();

        // 优先从配置文件获取腾讯云认证信息，如果未设置则从环境变量获取
        String secretId = config.getCredentials().getSecretId();
        String secretKey = config.getCredentials().getSecretKey();

        // 如果配置文件中未设置，则尝试从环境变量获取
        if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
            secretId = System.getenv(config.getCredentials().getSecretIdEnv());
            secretKey = System.getenv(config.getCredentials().getSecretKeyEnv());

            if (secretId == null || secretKey == null) {
                throw new RuntimeException(String.format(
                    "未找到腾讯云认证信息，请在配置文件中设置secretId和secretKey，或设置环境变量 %s 和 %s",
                    config.getCredentials().getSecretIdEnv(),
                    config.getCredentials().getSecretKeyEnv()
                ));
            }
        }

        try {
            // 实例化一个认证对象
            Credential cred = new Credential(secretId, secretKey);

            // 实例化一个 HTTP 选项，可选，无特殊需求时可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint(config.getEndpoint());

            // 实例化一个客户端配置对象
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            // 实例化要请求产品的 client 对象
            this.client = new TiiaClient(cred, config.getRegion(), clientProfile);
            log.info("成功初始化腾讯云图像识别客户端");

        } catch (Exception e) {
            log.error("初始化腾讯云图像识别客户端失败", e);
            throw new RuntimeException("无法初始化图像识别服务", e);
        }
    }

    /**
     * 对一组图像进行识别
     * @param imagePaths 图像文件路径列表
     * @return 每个图像的识别结果
     */
    @Override
    public Map<Path, List<RecognitionResult>> recognizeImages(List<Path> imagePaths) {
        Map<Path, List<RecognitionResult>> results = new HashMap<>();

        for (Path imagePath : imagePaths) {
            try {
                log.debug("正在分析图像: {}", imagePath.getFileName());

                // 读取图像文件并转换为 Base64
                byte[] imageBytes = Files.readAllBytes(imagePath);
                String base64Image = Base64.getEncoder().encodeToString(imageBytes);

                // 创建请求对象
                DetectLabelRequest req = new DetectLabelRequest();
                req.setImageBase64(base64Image);

                // 调用接口获取图像识别结果
                DetectLabelResponse resp = client.DetectLabel(req);
                DetectLabelItem[] labels = resp.getLabels();

                // 转换结果
                List<RecognitionResult> imageResults = new ArrayList<>();
                Arrays.stream(labels)
                        .limit(config.getRecognition().getMaxResults()) // 使用配置的最大结果数
                        .forEach(label -> imageResults.add(new RecognitionResult(
                                label.getName(),
                                label.getConfidence() / 100.0 // 转换置信度为0-1范围
                        )));

                results.put(imagePath, imageResults);

            } catch (IOException e) {
                log.error("读取图像文件时发生错误: " + imagePath.getFileName(), e);
                // 继续处理下一个图像
            } catch (TencentCloudSDKException e) {
                log.error("调用腾讯云图像识别服务时发生错误: " + imagePath.getFileName(), e);
                // 继续处理下一个图像
            }
        }

        log.info("完成 {} 张图像的识别", results.size());
        return results;
    }

    /**
     * 关闭资源（此实现不需要特别的清理操作）
     */
    @Override
    public void close() {
        // 腾讯云客户端不需要显式关闭
    }
}
